home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / jockguts.arc / MENUTTT5.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-28  |  25KB  |  632 lines

  1. {--------------------------------------------------------------------------}
  2. {                         TechnoJock's Turbo Toolkit                       }
  3. {                                                                          }
  4. {                              Version   5.01                              }
  5. {                                                                          }
  6. {                                                                          }
  7. {              Copyright 1986, 1989 TechnoJock Software, Inc.              }
  8. {                           All Rights Reserved                            }
  9. {                          Restricted by License                           }
  10. {--------------------------------------------------------------------------}
  11.  
  12.                      {--------------------------------}
  13.                      {       Unit:  MenuTTT5          }
  14.                      {--------------------------------}
  15.  
  16.  
  17. {History:     2/13/89       Mod 5.00a changed Y2 calculation in proc
  18.                             Determine_Y_Dimensions
  19. }
  20.  
  21. {$S-,R-,V-,D-}
  22.  
  23. Unit MenuTTT5;
  24.  
  25. INTERFACE
  26.  
  27. Uses CRT, FastTTT5, DOS, WinTTT5, KeyTTT5, StrnTTT5;
  28.  
  29. const
  30.    Max_Choices = 30;
  31.    MenuStrLength = 40;     {make longer if necessary}
  32. type
  33. {$IFDEF VER50}
  34.    Menu_Hook = Procedure(var Ch:char; Choice:integer; var Ecode:integer);
  35. {$ENDIF}
  36.    Menu_record = record
  37.                   Heading1     : string[MenuStrLength];   { '' for no heading}
  38.                   Heading2     : string[MenuStrLength];
  39.                   Topic        : array[1..Max_Choices] of string[MenuStrLength];
  40.                   TotalPicks   : integer;
  41.                   PicksPerLine : byte;
  42.                   AddPrefix    : byte;                    {0 no, 1 No.'s, 2 Lets}
  43.                   TopLeftXY    : array[1..2] of byte;     {X,Y}
  44.                   Boxtype      : byte;                    {0,1,2,3, >3}
  45.                   Colors       : array[1..5] of byte;     {HF,HB,LF,LB,Box}
  46.                   Margins      : byte;
  47.                   AllowEsc     : boolean;                 {true if Esc will exit}
  48.                   {$IFDEF VER50}
  49.                   Hook         : Menu_hook;
  50.                   {$ENDIF}
  51.                 end;
  52. {$IFNDEF VER50}
  53. Var
  54.   M_UserHook : Pointer;
  55. {$ENDIF}
  56. Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  57. Procedure Menu_Set(var M : Menu_record);
  58. Procedure DisplayMenu(MenuDef: Menu_record;
  59.                       Window:Boolean;
  60.                       var Choice,Errorcode : integer);
  61.  
  62. IMPLEMENTATION
  63.  
  64. {$IFNDEF VER50}
  65.    Procedure Call_Hook(var Ch:char; Choice:integer; var Ecode:integer);
  66.           Inline($FF/$1E/M_UserHook);
  67. {$ENDIF}
  68.  
  69. {$F+}
  70.  Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  71.  {}
  72.  begin
  73.  end; {of proc No_Hook}
  74. {$F-}
  75.  
  76.  Procedure Menu_Set(var M : Menu_record);
  77.  {}
  78.  begin
  79.      with M do
  80.      begin
  81.          Heading1     := '';
  82.          Heading2     := '';
  83.          Topic[1]     := '';
  84.          TotalPicks   := 0;
  85.          PicksPerLine := 1;
  86.          AddPrefix    := 1;
  87.          TopLeftXY[1] := 0;
  88.          TopLeftXY[2] := 0;
  89.          Boxtype      := 5;
  90.          If BaseOfScreen = $B800 then
  91.          begin
  92.              Colors[1]    := white;
  93.              Colors[2]    := red;
  94.              Colors[3]    := lightgray;
  95.              Colors[4]    := blue;;
  96.              Colors[5]    := lightred;
  97.          end
  98.          else
  99.          begin
  100.              Colors[1]    := white;
  101.              Colors[2]    := black;
  102.              Colors[3]    := lightgray;
  103.              Colors[4]    := black;
  104.              Colors[5]    := white;
  105.          end;
  106.          Margins      := 5;
  107.          AllowEsc     := true;
  108.          {$IFDEF VER50}
  109.                  Hook         := NO_Hook;
  110.          {$ELSE}
  111.                  M_UserHook := Nil;
  112.          {$ENDIF}
  113.      end;
  114.  end; {of proc Menu_Set}
  115.  
  116.  Procedure MenuError(Code:byte);    {fatal error -- msg and halt}
  117.  var Message:string;
  118.  begin
  119.      {Clrscr;}
  120.      Case Code of
  121.      1 : Message := 'Fatal Error 1: Too Many Picks to display. Change PicksPerLine';
  122.      else Message := 'Aborting';
  123.      end; {case}
  124.      WriteAT(1,12,black,lightgray,Message);
  125.      Repeat Until keypressed;
  126.      Halt;
  127.  end;    {proc MenuError}
  128.  
  129. Procedure DisplayMenu(MenuDef: Menu_record;
  130.                       Window:Boolean;
  131.                       var Choice,Errorcode : integer);
  132. Const
  133. Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  134. Numbers  = '123456789';
  135. var
  136. I,J,X2,Y2,heading_Lines : integer;
  137. TextWidth : byte;
  138.  
  139.  
  140.     Function Int_to_Str(Number:Integer):string;
  141.     var Temp : string;
  142.     begin
  143.        Str(Number,temp);
  144.        Int_to_Str := temp;
  145.     end;
  146.  
  147.     Function  Str_to_Int(Str:string):integer;
  148.     var temp,code : integer;
  149.     begin
  150.         If length(Str) = 0 then
  151.            Str_to_Int := 0
  152.         else
  153.         begin
  154.             val(Str,temp,code);
  155.             if code = 0 then
  156.                Str_to_Int := temp
  157.             else
  158.                Str_to_Int := 0;
  159.         end;
  160.     end;
  161.  
  162.    Procedure GetDimensions;
  163.    var Fullwidth,MaxWidth: integer;
  164.  
  165.      Procedure Validate_Prefix;                          { 0   no prefix  }
  166.      begin                                               { 1   numbers prefix}
  167.          with MenuDef do                                 { 2   letters prefix}
  168.          begin                                           { 3   function key prefix}
  169.              If PicksPerLine < 1 then PicksPerLine := 1; { 4   capital letter selection}
  170.              If (TotalPicks = 10) and (AddPrefix = 1) then
  171.                 AddPrefix := 3;
  172.              If (TotalPicks > 10) and (AddPrefix in [1,3]) then
  173.                 AddPrefix := 2;
  174.              If (Addprefix > 4) or (TotalPicks > 26) or (Addprefix < 0) then
  175.                 Addprefix := 0;
  176.              end; {do}
  177.      end; {Validate_Prefix}
  178.  
  179.    Procedure Add_Prefix;
  180.    var I : integer;
  181.    begin
  182.        With MenuDef do
  183.        begin
  184.            Case AddPrefix of
  185.            1 : for I := 1 to TotalPicks do
  186.                    Topic[I] := int_to_str(I) + ' ' + Topic[I];
  187.            2 : for I := 1 to TotalPicks do
  188.                    Topic[I] := Copy(Alphabet,I,1) + ' ' + Topic[I];
  189.            3 : If TotalPicks < 10 then
  190.                   for I := 1 to TotalPicks do
  191.                       Topic[I] := 'F'+Int_to_Str(I) + ' ' + Topic[I]
  192.                else
  193.                begin                           {add extra space for F10 }
  194.                    for I := 1 to 9 do
  195.                        Topic[I] := 'F'+Int_to_Str(I) + '  ' + Topic[I];
  196.                    Topic[10] := 'F10 '+ Topic[10];
  197.                end;
  198.            end; {case}
  199.        end;  {do}
  200.    end;  {proc Add_Prefix}
  201.  
  202.      Procedure Find_Longest_Topic;
  203.      var
  204.        I,J: integer;
  205.      begin
  206.          with MenuDef do
  207.          begin
  208.              Textwidth := 0;
  209.              For I := 1 to TotalPicks do
  210.                  If length(Topic[I]) > TextWidth then
  211.                     Textwidth := length(Topic[I]);         {find the longest text}
  212.          end;  {with}
  213.      end;   {Proc Find_Widest_Line}
  214.  
  215.    Procedure Adjust_Text_Width(Len:integer);
  216.    var I,J : integer;
  217.    begin
  218.        With MenuDef do
  219.        begin
  220.            For I := 1 to TotalPicks do
  221.                If length(Topic[I]) > Len then         {reduce it}
  222.                   Delete(Topic[I],succ(Len),length(Topic[I]) - Len)
  223.                else                                  {expand it}
  224.                   For J := length(Topic[I]) + 1 to Textwidth do
  225.                       Topic[I] :=  Topic[I] + ' ';
  226.        end; {do}
  227.    end;
  228.  
  229.    Procedure Determine_MaxWidth;
  230.    {findout the max internal menu space - MaxWidth}
  231.    begin
  232.        with MenuDef do
  233.        begin
  234.            If margins < 0 then Margins := 0;
  235.            If not (BoxType in [0..9]) then
  236.               BoxType := 0;
  237.            MaxWidth := 80 - 2*Margins - 1; {-1 for arrow symbol to left of pick}
  238.            Case BoxType of
  239.            1..4 : MaxWidth := MaxWidth - 2;     {box sides}
  240.            5    : MaxWidth := pred(MaxWidth);    {box shadow}
  241.            6..9 : MaxWidth := MaxWidth - 3;     {box sides and shadow}
  242.            end;
  243.        end; {with}
  244.    end;
  245.  
  246.    Procedure Validate_PicksPerLine;
  247.    begin
  248.        With MenuDef do
  249.        begin
  250.            If succ(TextWidth)*PicksPerLine <= MaxWidth then
  251.               exit;  {no adjustment necessary, everything fits}
  252.            If (TextWidth-2)*PicksPerLine <= Maxwidth  then
  253.                TextWidth := pred(MaxWidth div PicksperLine)
  254.            else
  255.            begin
  256.                While succ(TextWidth)*PicksPerLine > MaxWidth do
  257.                      PicksPerLine := pred(PicksPerLine);
  258.                If PicksPerLine = 0 then
  259.                begin
  260.                    TextWidth := pred(MaxWidth);
  261.                    PicksPerLine := 1;
  262.                end;
  263.            end;
  264.        end; {with}
  265.    end;  {Proc Validate_PicksPerLine}
  266.  
  267.    Procedure Determine_X_Dimensions;
  268.    {Checks to see if the menu will fit, if it won't it changes something!}
  269.    begin
  270.        With MenuDef do
  271.        begin
  272.            Fullwidth := succ(Textwidth)*PicksPerLine + 2*Margins;
  273.            Case BoxType of
  274.            1..4 : FullWidth := FullWidth + 2;     {box sides}
  275.            5    : FullWidth := succ(FullWidth);   {box shadow}
  276.            6..9 : FullWidth := FullWidth + 3;     {box sides and shadow}
  277.            end; {Case}
  278.            If TopleftXY[1] < 1 then
  279.               TopleftXY[1] := (80 - Fullwidth)  div 2;
  280.            If TopLeftXY[1] + Fullwidth < 80 then
  281.               X2 := TopleftXY[1] + Fullwidth
  282.            else
  283.            begin
  284.                X2 := 80;
  285.                TopLeftXY[1] := 80 - Fullwidth + 1;
  286.            end;
  287.        end; {with}
  288.    end; {Proc Determine_X_Dimensions}
  289.  
  290.    Procedure Determine_Y_Dimensions;
  291.    var
  292.       BoxLines,
  293.       TopicLines,
  294.       FullDepth  : integer;
  295.    begin
  296.        With MenuDef do
  297.        begin
  298.            TopicLines := TotalPicks div PicksPerLine;  {no of full rows of picks}
  299.            If TotalPicks mod PicksPerLine > 0 then     {+1 if partial row of picks}
  300.               TopicLines := succ(TopicLines);
  301.            Case BoxType of
  302.            0    : Boxlines := 0;
  303.            1..5 : BoxLines :=  2;     {box sides}
  304.            6..9: BoxLines :=  3;     {box sides and shadow}
  305.            end;
  306.            Heading_Lines := 0;
  307.            If length(Heading1) > 0 then
  308.               Heading_Lines := succ(Heading_Lines);
  309.            If length(Heading2) > 0 then
  310.               Heading_Lines := succ(Heading_Lines);
  311.            If Heading_Lines > 0 then                   {add a line for a gap}
  312.               Heading_Lines := succ(Heading_Lines);    {gap above topics}
  313.            If BoxType = 5 then
  314.               Heading_Lines := succ(Heading_Lines);
  315.            Fulldepth := BoxLines+TopicLines+Heading_Lines;
  316.            If Heading_Lines > 0 then
  317.              Fulldepth := succ(Fulldepth);  {+1 gap below topics if headings}
  318.            If FullDepth > DisplayLines then   {if it doesn't fit, drop off topics}
  319.            begin
  320.                If Heading_Lines > 0 then
  321.                   TotalPicks :=  (DisplayLines - BoxLines -Heading_Lines-1)*PicksPerLine
  322.                else
  323.                   TotalPicks :=  (DisplayLines - BoxLines - Heading_Lines)*PicksPerLine;
  324.                FullDepth := 25;
  325.            end;
  326.            If TopLeftXY[2] <= 0 then
  327.               TopLeftXY[2] := (DisplayLines - Fulldepth) div 2 +1;
  328.            If TopLeftXY[2] + Fulldepth - 1 <= DisplayLines then
  329.            begin
  330.                If BoxType > 4 then   {shadow}
  331.                   Y2 := TopleftXY[2] + (Fulldepth) - 2     {Mod 5.00a}
  332.                else
  333.                   Y2 := TopleftXY[2] + pred(Fulldepth);    {Mod 5.00a}
  334.            end
  335.            else
  336.            begin
  337.                If BoxType > 4 then   {shadow}
  338.                   Y2 := pred(DisplayLines)
  339.                else
  340.                   Y2 := DisplayLines;
  341.                TopLeftXY[2] := DisplayLines - Fulldepth {+ 1};   {WZ}
  342.            end;
  343.    end;   {do}
  344.    end; {Proc Determine_Y_Dimensions}
  345.  
  346.    begin                              {Get_Dimensions}
  347.        Validate_Prefix;
  348.        Add_Prefix;
  349.        Find_Longest_Topic;
  350.        Determine_MaxWidth;
  351.        Validate_PicksPerLine;
  352.        Adjust_Text_Width(TextWidth);
  353.        Determine_X_Dimensions;
  354.        Determine_Y_Dimensions;
  355.    end;   {proc GetDimensions}
  356.  
  357.    Procedure Write_Text(Item:integer;Highlight:boolean);
  358.    Var X,Y,A:integer;
  359.    begin
  360.        With MenuDEf do
  361.        begin
  362.            A := Item mod PicksPerLine;
  363.            Y := Item div PicksPerLine +TopleftXY[2] + ord(A <> 0);
  364.            Y := Y + Heading_lines - ord(Boxtype = 0);
  365.            If A = 0 then A := PicksPerLine;      {A is now the no of picks from left}
  366.            X := (A - 1)*(TextWidth + 1)+Margins+
  367.                 TopleftXY[1]+1 + ord(BoxType > 0);          {title width + 1 for a space}
  368.            If Highlight then
  369.            begin
  370.                WriteAt(X,Y,colors[1],colors[2],Topic[item]);
  371.                WriteAT(pred(X),Y,colors[5],colors[2],chr(16));  {write arrow head}
  372.            end
  373.            else
  374.            begin
  375.                WriteAT(X,Y,colors[3],colors[4],Topic[item]);
  376.                WriteAT(pred(X),Y,colors[3],colors[4],' ');       {remove arrow head}
  377.                If AddPrefix = 4 then                             {highlight the capital letter}
  378.                   WriteAT(Pred(X)+First_Capital_Pos(Topic[Item]),Y,
  379.                           colors[1],colors[4],
  380.                           First_Capital(Topic[Item]));
  381.            end;
  382.        end;  {do}
  383.    end;  {Proc Write_Text}
  384.  
  385.    Procedure CreateMenu;
  386.    var I : integer;
  387.    begin
  388.    with MenuDef do
  389.    begin
  390.     If Window then
  391.            MkWin(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4],boxtype)
  392.     else
  393.     begin
  394.         ClearText(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4]);
  395.         If (BoxType in [5..9]) and (TopleftXY[1] > 1) then      {draw a shadow}
  396.         begin
  397.             For I := TopleftXY[2]+1 to Y2+1 do
  398.                 WriteAt(pred(TopLeftXY[1]),I,colors[3],black,' ');
  399.             WriteAt(TopLeftXY[1],succ(Y2),colors[3],black,
  400.                 replicate(X2-succ(TopLeftXY[1]),' '));
  401.         end;
  402.     end;
  403.     Case Boxtype of
  404.     1..4: Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype);
  405.     5   : begin
  406.               WriteAT(TopleftXY[1],TopleftXY[2],colors[5],colors[4],
  407.                       replicate(succ(X2 - TopleftXY[1]),chr(223)));
  408.               WriteAT(TopleftXY[1],TopleftXY[2]+Heading_Lines-1,colors[5],colors[4],
  409.                       replicate(succ(X2 - TopleftXY[1]),chr(196)));
  410.           end;
  411.     6..9:Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype-5);
  412.     end; {case}
  413.  
  414.     If length(Heading1) > 0 then
  415.        WriteBetween(TopleftXY[1],X2,
  416.                     TopLeftXY[2]+ord(BoxType > 0),
  417.                     colors[1],colors[4],Heading1);
  418.     If length(Heading2) > 0 then
  419.        WriteBetween(TopleftXY[1],X2,
  420.                     TopLeftXY[2]+ord(BoxType > 0)+ord(Heading_Lines <> 2),
  421.                     colors[1],colors[4],Heading2);
  422.     For I := 1 to TotalPicks do
  423.         Write_Text(I,false);
  424.     Write_Text(Choice,True);       {Highlight Default}
  425.    end; {do}
  426.    end; {Proc CreateMenu}
  427.  
  428.    Procedure Process_Keystrokes;
  429.    var
  430.      Found,
  431.      Selected: Boolean;
  432.      ChT,
  433.      CHpk:char;
  434.      Oldchoice:integer;
  435.      I,
  436.      Ecode:integer;
  437.      ScanTop,ScanBot,Cx,Cy : byte;
  438.    begin
  439.        Selected := false;
  440.        Found := false;
  441.        FindCursor(Cx,Cy,ScanTop,ScanBot);
  442.        OffCursor;
  443.        With MenuDef do
  444.        begin
  445.        Repeat
  446.              Chpk := GetKey;
  447. {$IFDEF VER50}
  448.              MenuDef.Hook(Chpk,Choice,Ecode);   {call the user hook}
  449. {$ELSE}
  450.              If M_UserHook <> Nil then
  451.                 Call_Hook(Chpk,Choice,Ecode);
  452. {$ENDIF}
  453.              Case upcase(CHpk) of
  454.              #208 : begin       {Cursor Down}
  455.                         Write_text(Choice,false);
  456.                         Choice := Choice + PicksPerLine;
  457.                         If Choice > TotalPicks then
  458.                            Choice := (Choice mod PicksPerLine) + 1;
  459.                         Write_Text(Choice,true);
  460.                     end;
  461.              #129 : If Choice + PicksPerLine  <= TotalPicks then  {Mouse Down}
  462.                     begin
  463.                         Write_text(Choice,false);
  464.                         Choice := Choice + PicksPerLine;
  465.                         Write_Text(Choice,true);
  466.                     end;
  467.              #200 : begin       {cursor up}
  468.                         Write_Text(Choice,false);
  469.                         Choice := Choice - PicksPerLine;
  470.                         If Choice < 1 then
  471.                         begin
  472.                            Choice := Choice + PicksPerline;
  473.                            Choice :=
  474.                              ((TotalPicks div PicksPerLine)*PicksPerLine)
  475.                              - PicksPerLine + 1 + Choice - 2;
  476.                            If Choice + PicksPerLine <= TotalPicks then
  477.                               Choice := Choice + PicksPerLine;   {phew!}
  478.                         end;
  479.                         Write_Text(Choice,true);
  480.                     end;
  481.              #128 : If Choice - PicksPerLine > 0 then   {Mouse up}
  482.                     begin
  483.                         Write_Text(Choice,false);
  484.                         Choice := Choice - PicksPerLine;
  485.                         Write_Text(Choice,true);
  486.                     end;
  487.              #203 : begin       {cursor left}
  488.                         Write_Text(Choice,False);
  489.                         Choice := pred(choice);
  490.                         If choice = 0 then Choice := TotalPicks;
  491.                         Write_Text(Choice,true);
  492.                     end;
  493.              #130 : If (pred(Choice) > 0)  {mouse left}
  494.                     and ( Choice mod PicksPerLine <> 1) then
  495.                     begin
  496.                         Write_Text(Choice,False);
  497.                         Choice := pred(choice);
  498.                         Write_Text(Choice,true);
  499.                     end;
  500.              ' ',
  501.              #205 : begin        {cursor right}
  502.                         Write_Text(Choice,false);
  503.                         Choice := succ(Choice);
  504.                         If choice > TotalPicks then Choice := 1;
  505.                         Write_Text(Choice,true);
  506.                     end;
  507.              #131 : If (succ(Choice) <= TotalPicks) {Mouse right}
  508.                     and ( Choice mod PicksPerLine <> 0) then
  509.                     begin
  510.                         Write_Text(Choice,false);
  511.                         Choice := succ(Choice);
  512.                         Write_Text(Choice,true);
  513.                     end;
  514.              #199 : begin         {home key}
  515.                         Write_Text(Choice,false);
  516.                         Choice := 1;
  517.                         Write_Text(Choice,true);
  518.                     end;
  519.              #207 : begin         {end key}
  520.                         Write_Text(Choice,false);
  521.                         Choice := TotalPicks;
  522.                         Write_Text(Choice,true);
  523.                     end;
  524.              #133,                 {Mouse enter}
  525.              #13  : begin          {enter key}
  526.                         Selected := true;
  527.                         Errorcode := 0;
  528.                     end;
  529.              #0   : begin
  530.                         Selected := true;
  531.                         ErrorCode := Ecode;
  532.                     end;
  533.              #132,                    {Mouse Esc}
  534.              #27  : If AllowEsc then  {Esc}
  535.                     begin
  536.                         Selected := true;
  537.                         ErrorCode := 1;
  538.                     end
  539.                     else
  540.                     begin
  541.                         Write_Text(Choice,false);
  542.                         Choice := TotalPicks;
  543.                         Write_Text(Choice,true);
  544.                     end;
  545.              #187..#196 : If Addprefix = 3 then   {F1 to F10}
  546.                           begin
  547.                               Oldchoice := Choice;
  548.                               Case Upcase(Chpk) of
  549.                               #187 : If TotalPicks >= 1  then choice := 1 else choice := 0;
  550.                               #188 : If TotalPicks >= 2  then choice := 2 else choice := 0;
  551.                               #189 : If TotalPicks >= 3  then choice := 3 else choice := 0;
  552.                               #190 : If TotalPicks >= 4  then choice := 4 else choice := 0;
  553.                               #191 : If TotalPicks >= 5  then choice := 5 else choice := 0;
  554.                               #192 : If TotalPicks >= 6  then choice := 6 else choice := 0;
  555.                               #193 : If TotalPicks >= 7  then choice := 7 else choice := 0;
  556.                               #194 : If TotalPicks >= 8  then choice := 8 else choice := 0;
  557.                               #195 : If TotalPicks >= 9  then choice := 9 else choice := 0;
  558.                               #196 : If TotalPicks >= 10 then choice := 10 else choice := 0;
  559.                               end;  {case}
  560.                               If Choice = 0 then
  561.                                  Choice := Oldchoice
  562.                               else
  563.                               begin
  564.                                   Write_Text(Oldchoice,false);
  565.                                   Write_Text(Choice,true);
  566.                                   Selected := true;
  567.                                   Errorcode := 0;
  568.                               end;
  569.                           end;
  570.              '0'..'9': If (AddPrefix in [1,3]) then   {Number or Function Prefix} {4.02}
  571.                        begin
  572.                            If (Str_to_int(CHpk) in [1..TotalPicks]) then
  573.                            begin
  574.                                Write_Text(Choice,false);
  575.                                Choice := Str_to_Int(CHpk);
  576.                                Write_Text(Choice,true);
  577.                                Selected := true;
  578.                                ErrorCode := 0;
  579.                            end;
  580.                        end;
  581.              'A'..'Z': If AddPrefix = 2 then
  582.                        begin
  583.                           If (pos(upcase(CHpk),Alphabet) in [1..TotalPicks]) then
  584.                           begin
  585.                               Write_Text(Choice,false);
  586.                               Choice := pos(upcase(CHpk),Alphabet);
  587.                               Write_Text(Choice,true);
  588.                               Selected := true;
  589.                               Errorcode := 0;
  590.                           end;
  591.                        end
  592.                        else
  593.                        begin
  594.                            If AddPrefix = 4 then
  595.                            begin
  596.                                Found := false;
  597.                                I := Choice;
  598.                                Repeat
  599.                                     If First_Capital(Topic[I]) = upcase(ChPk) then
  600.                                     begin
  601.                                         Found := true;
  602.                                         Write_Text(Choice,false);
  603.                                         Choice := I;
  604.                                         Write_Text(Choice,true);
  605.                                         Selected := true;
  606.                                         Errorcode := 0;
  607.                                     end
  608.                                     else
  609.                                         If I = TotalPicks then
  610.                                            I := 1
  611.                                         else
  612.                                            Inc(I);
  613.                                Until Found or (I = Choice);
  614.                            end;
  615.                         end;
  616.                     end;
  617.        Until Selected;
  618.        SizeCursor(ScanTop,ScanBot);
  619.        end; {do}
  620.   end; {proc Process_keystrokes}
  621.  
  622. begin
  623.    GetDimensions;
  624.    CreateMenu;
  625.    Horiz_Sensitivity := 2;  {two cursors left/right before mouse returns a keypress}
  626.    Process_Keystrokes;
  627.    If Window then RmWin;
  628. end;        {Main Procedure DisplayMenu}
  629.  
  630. begin
  631. end.
  632.